const execsh = require('exec-sh')
const chalk = require('chalk')
const { promise: execShPromise } = execsh

/**
 * execsh执行单条指令，允许传入自定义回调
 * @param {string} command 需要执行的语句
 * @param {string} errlog 执行错误提示语句
 * @param {(error:{code: number, stderr: string, stdout: string})=> void} callBack 错误时回调函数
 */
function execSh(command, errlog, callBack, isShowOut = false) {
    // 执行指定命令并隐藏命令输出，若存在指定回调，则执行回调函数；反之则执行默认操作
    return execsh(command, !isShowOut, (err) => {
        if (callBack) {
            callBack(err)
        } else if (err && err.code && err.code !== 0) {
            console.log(chalk.red(errlog || err.code))
        }
    })
}

/**
 * execsh promise 执行，用于多命令同时执行，允许传入自定义回调
 * @param {Array<{cmd: string, log: string}>} commands 需要执行的语句
 * @param {({stderr: string, stdout: string})=> void} callBack
 */
async function execPromise(commands, callBack) {
    if (Array.isArray(commands)) {
        return Promise.all(
            commands.map(async (command) => {
                const { cmd, log, tag } = command
                try {
                    /**
                     * out = { stderr: '', stdout: '' }
                     * stderr 指令执行的错误信息
                     * stdout 指令执行成功后的输出
                     */
                    const out = await execShPromise(cmd, true)
                    if (callBack) {
                        callBack(out)
                    }
                    return {
                        success: true,
                        out: out.stdout,
                        tag,
                    }
                } catch (error) {
                    /**
                     * error = { code: 1, stderr: '', stdout: '' }
                     * code 错误码
                     * stderr 指令执行的错误信息
                     * stdout 指令执行成功后的输出
                     */
                    // 输出指令执行的默认错误
                    // console.log(chalk.red(`Exit code:${error.code}：${error.stderr}`))
                    // 输出指令指定的log
                    console.log(chalk.red(log))
                    return {
                        success: false,
                        out: error.stderr,
                        tag,
                    }
                }
            }),
        )
    }
}

module.exports = { execPromise, execSh }
